package com.leyou.gateway.filters;

import com.leyou.common.auth.entity.Payload;
import com.leyou.common.auth.utils.JwtUtils;
import com.leyou.common.auth.utils.UserInfo;
import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exception.LyException;
import com.leyou.common.utils.CookieUtils;
import com.leyou.gateway.config.FilterProperties;
import com.leyou.gateway.config.JwtProperties;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import io.jsonwebtoken.Jwt;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.FORM_BODY_WRAPPER_FILTER_ORDER;

@Slf4j
@Component
@EnableConfigurationProperties({JwtProperties.class, FilterProperties.class})
public class AuthFilter extends ZuulFilter {

    @Autowired
    private JwtProperties prop;

    @Autowired
    private FilterProperties filterProp;

    //过滤器类型 指定经过过滤器前或者后执行
    @Override
    public String filterType() { return FilterConstants.PRE_TYPE; }

    //指定过滤器执行的顺序，数字越小越先执行
    @Override
    public int filterOrder() {
        return FORM_BODY_WRAPPER_FILTER_ORDER + 1;
    }

    //是否开启当前过滤器 true表示开启
    @Override
    public boolean shouldFilter() {
        return true;
    }


    //过滤器中的业务
    @Override
    public Object run() throws ZuulException {
        //这样为了获取cookie
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();

        //便利白名单
        String requestURL = request.getRequestURI();
        for (String allowPath : filterProp.getAllowPaths()) {
            if (requestURL.startsWith(allowPath)) {
                //中止后续操作，但是依然会继续访问处理器
                return null;

            }
        }

        try {
            //获取token,得不到就说明验证不通过
            String lyToken = CookieUtils.getCookieValue(request, prop.getUser().getCookieName());
            // 获取token中的用户信息,这样就能获取角色信息,传给后面
            Payload<UserInfo> payload = JwtUtils.getInfoFromToken(lyToken, prop.getPublicKey(), UserInfo.class);

            //获取当前用户的角色信息
            String role = payload.getUserInfo().getRole();
            //把角色信息传给其他微服务,包用户id给传过去
            ctx.addZuulRequestHeader("role", role);
            ctx.addZuulRequestHeader("userId",payload.getUserInfo().getId().toString());
            //return null表示中止当前业务方法，但是依然会继续向下访问。
            return null;
        } catch (Exception e) {  //但是这里不能拦截某些访问

            //没有登录，阻止当前请求继续
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(403);
            throw new LyException(ExceptionEnum.NO_AUTH_ERROR);
        }
    }
}
